/*
 * Copyright (c) 2018-2999 九五云信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.model.Delivery;
import com.yami.shop.common.bean.Quick100;
import com.yami.shop.common.bean.QuickBird;
import com.yami.shop.common.util.BmapPoint;
import com.yami.shop.common.util.GraphUtils;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.dao.DeliveryMapper;
import com.yami.shop.service.DeliveryService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lgh on 2018/11/26.
 */
@Service
@AllArgsConstructor
public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> implements DeliveryService {

    private final ShopConfig shopConfig;

    @Override
    public String query(Long dvyId, String expNo) throws UnsupportedEncodingException {
        // 快递鸟查询
        QuickBird quickBird = shopConfig.getQuickBird();
        if (quickBird.getIsOpen()) {
            Delivery delivery = this.getById(dvyId);
            return queryByQuickBird(delivery.getDvyNo(), expNo);
        }

        // 快递100查询
        Quick100 quick100 = shopConfig.getQuick100();
        if (quick100.getIsOpen()) {
            Delivery delivery = this.getById(dvyId);
            return queryByQuick100(delivery.getDvyNoHd(), expNo);
        }
        return null;
    }

    /**
     * 通过快递鸟查询
     *
     * @param expCode 物流公司编码
     * @param expNo   物流单号
     * @return
     * @throws UnsupportedEncodingException
     */
    private String queryByQuickBird(String expCode, String expNo) throws UnsupportedEncodingException {
        QuickBird quickBird = shopConfig.getQuickBird();

        String requestData = "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
        params.put("EBusinessID", quickBird.getEBusinessID());
        String dataSign = Base64.encode(new Digester(DigestAlgorithm.MD5).digestHex(requestData + quickBird.getAppKey()), "UTF-8");
        params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
        params.put("RequestType", "1002");
        params.put("DataType", "2");
        String repJson = HttpUtil.post(quickBird.getReqUrl(), params);
        return repJson;
    }

    /**
     * 通过快递100查询
     *
     * @param expCode 物流公司编码
     * @param expNo   物流单号
     * @return
     */
    private String queryByQuick100(String expCode, String expNo) {
        Quick100 quick100 = shopConfig.getQuick100();
//        String param = "{\"com\":\"" + expCode + "\",\"num\":\"" + expNo + "\",\"order\":\"asc\"}"; //同下paramMap
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("com",expCode);
        paramMap.put("num",expNo);
        paramMap.put("order","asc");
        String param = JSON.toJSONString(paramMap);
        String sign = new Digester(DigestAlgorithm.MD5).digestHex(param+ quick100.getKey() + quick100.getCustomer(), "UTF-8").toUpperCase();
        Map<String, Object> params = new HashMap<>();
        params.put("param", param);
        params.put("sign", sign);
        params.put("customer", quick100.getCustomer());
        String repJson = HttpUtil.post(quick100.getReqUrl(), params);
        repJson=fmJson(repJson);
        return repJson;
    }

    /**
     * 快递100返回的json 转 快递鸟类型的json
     * （待优化）
     * form:
     * {"status":"200",
     * "state":"0",
     * "data":[
     * {
     * "context":"上海分拨中心/装件入车扫描 ",
     * "time":"2012-08-28 16:33:19",
     * "ftime":"2012-08-28 16:33:19",
     * },
     * {
     * "context":"上海分拨中心/下车扫描 ",
     * "time":"2012-08-27 23:22:42",
     * "ftime":"2012-08-27 23:22:42",
     * }]
     * }
     * --------------------------------------------------------
     * to:
     * {
     * "State": 3,
     * "Traces": [
     * {
     * "AcceptTime": "2014/06/25 08:05:37",
     * "AcceptStation": "正在派件..(派件人:邓裕富,电话:18718866310)[深圳 市]",
     * "Remark": null
     * },
     * {
     * "AcceptTime": "2014/06/25 04:01:28",
     * "AcceptStation": "快件在 深圳集散中心 ,准备送往下一站 深圳 [深圳市]",
     * "Remark": null
     * }
     * }
     */
    private String fmJson(String repJson) {

        JSONObject jb = JSONObject.parseObject(repJson);

        // 判断是否请求正常
        Integer status = jb.getInteger("status");
        if (status == null || status!=200) return "{ \"State\": 0,\"Traces\": []}";

        // map用于最后转成json
        Map<String, Object> map = new HashMap<>();
        // tracesList最后存入map中，储存物流详细信息
        List<Object> tracesList = new ArrayList<>();
        Integer state = jb.getInteger("state");
        String data = jb.getString("data");
        // dataList储存两个字段:AcceptTime、AcceptStation
        List<HashMap> dataList = JSON.parseArray(data, HashMap.class);
        for (int i = 0; i < dataList.size(); i++) {
            Map<String, Object> tracesMap = new HashMap<>();
            tracesMap.put("AcceptTime", dataList.get(i).get("ftime"));
            tracesMap.put("AcceptStation", dataList.get(i).get("context"));
            tracesList.add(tracesMap);
        }

        map.put("State", switchState(state));
        map.put("Traces", tracesList);
        String res = JSON.toJSONString(map);
        return res;
    }

    /**
     * 快递100的13种状态码转成快递鸟的6种
     *
     * @param state 快递100状态码
     *              0	 在途	快件处于运输过程中
     *              1	 揽收	快件已由快递公司揽收
     *              2	 疑难	快递100无法解析的状态，或者是需要人工介入的状态， 比方说收件人电话错误。
     *              3	 签收	正常签收
     *              4	 退签	货物退回发货人并签收
     *              5	 派件	货物正在进行派件
     *              6	 退回	货物正处于返回发货人的途中
     *              7	 转单	货物转给其他快递公司邮寄
     *              10 待清关	货物等待清关
     *              11 清关中	货物正在清关流程中
     *              12 已清关	货物已完成清关流程
     *              13 清关异常	货物在清关过程中出现异常
     *              14 收件人拒签	收件人明确拒收
     * @return 快递鸟状态码： 0:没有记录 1:已揽收 2:运输途中 201:达到目的城市 3:已签收 4:问题件
     */
    private Integer switchState(Integer state) {
        int i = 0;
        switch (state) {
            case 1:
                i = 1;
                break;
            case 5:
                i = 201;
                break;
            case 3:
                i = 3;
                break;
            case 0:
            case 7:
            case 10:
            case 11:
            case 12:
                i = 2;
                break;
            case 2:
            case 13:
            case 14:
            case 4:
            case 6:
                i = 4;
                break;
            default:
                break;
        }
        return i;
    }


    //TODO test
    public static void main(String[] args) {
        BmapPoint bmapPoint = new BmapPoint(116.404575, 39.918985);
        List<BmapPoint> bmapPoints = new ArrayList<>();
        bmapPoints.add(new BmapPoint(116.412732, 39.911707));
        bmapPoints.add(new BmapPoint(116.403928, 39.915277));
        bmapPoints.add(new BmapPoint(116.393652, 39.910794));
        bmapPoints.add(new BmapPoint(116.403461, 39.921336));
        boolean pointInPolygon = GraphUtils.isPointInPolygon(bmapPoint, bmapPoints);
        System.out.println(pointInPolygon);
    }


}
